package yunquan.wang.base.event;

import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;

public abstract class YunquanEventListener implements SmartApplicationListener{
	protected Log logger = LogFactory.getLog(this.getClass());
    private Set<Class<? extends ApplicationEvent>> supportedEvents;
    private Set<Class<?>> sourceTypes;
	private boolean explicitMatching = false;
 
	
	public void setSupportedEvents(
			Set<Class<? extends ApplicationEvent>> supportedEvents) {
		this.supportedEvents = supportedEvents;
	}

	public void setSourceTypes(Set<Class<?>> sourceTypes) {
		this.sourceTypes = sourceTypes;
	}

	public void setExplicitMatching(boolean explicitMatching) {
		this.explicitMatching = explicitMatching;
	}

	@Override
	public abstract void onApplicationEvent(ApplicationEvent event);
	
	@Override
	public int getOrder() {
		return 0;
	}
	@Override
	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
	    //If no supported events configured return true
	    if (this.supportedEvents == null) {
	        return true;
	    }
 
        if (this.explicitMatching) {
            return this.supportedEvents.contains(eventType);
        }
        //Check inheritance for includes match if no explicitly matching
        for (final Class<? extends ApplicationEvent> includedType : this.supportedEvents) {
            if (includedType.isAssignableFrom(eventType)) {
                return true;
            }
        }
        return false;
        
	}
	@Override
	public boolean supportsSourceType(Class<?> sourceType) {
		
	    //If no supported events configured return true
	    if (this.sourceTypes == null) {
	        return true;
	    }
 
        if (this.explicitMatching) {
            return this.sourceTypes.contains(sourceType);
        }
        
        //Check inheritance for includes match if no explicitly matching
        for (final Class<?> includedType : this.sourceTypes) {
            if (includedType.isAssignableFrom(sourceType)) {
                return true;
            }
        }
        return false;
	}

}
